import { memo, useState, useEffect, useRef } from 'react';
import { ReactMarkdown } from 'react-markdown/lib/react-markdown';
import Viewer from 'react-viewer';
import remarkGfm from 'remark-gfm';

import { Box, Link, Stack, Typography } from '@mui/material';

import Code from 'components/atoms/Code';
import ElementRef from 'components/atoms/element/ref';

import { IMessageElement } from 'state/element';
import { clientState } from 'state/client';
import { v4 as uuidv4 } from 'uuid';

import { loadingState, sessionState, voicingState, isRenderingState, messagesState } from 'state/chat';

import { useRecoilValue, useSetRecoilState, useRecoilState } from 'recoil';
import zantingIcon from 'assets/zanting-active.png';
import zantingDisabledIcon from 'assets/zanting-deactive.png';
import { render } from '@testing-library/react';



// import InlinedElements from './inlined';

interface Props {
  id?: string;
  content?: string;
  elements: IMessageElement[];
  language?: string;
  authorIsUser?: boolean;
  isRunning?: boolean
  isLast?:boolean
  isRendering?:boolean
  setRandom?: any
  random?: any
  type?: string
}

const isForIdMatch = (
  id: string | number | undefined,
  forIds: string[] | undefined
) => {
  if (!forIds || !forIds.length || !id) {
    return false;
  }

  return forIds.includes(id.toString());
};

const isGlobalMatch = (forIds: string[] | undefined) => {
  return !forIds || !forIds.length;
};

function escapeRegExp(string: string) {
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

function prepareContent({ id, elements, content, language }: Props) {
  const elementNames = elements.map((e) => escapeRegExp(e.name));

  // Sort by descending length to avoid matching substrings
  elementNames.sort((a, b) => b.length - a.length);

  const elementRegexp = elementNames.length
    ? new RegExp(`(${elementNames.join('|')})`, 'g')
    : undefined;

  let preparedContent = content ? content.trim() : '';
  const inlinedElements = elements.filter(
    (e) => isForIdMatch(id, e?.forIds) && e.display === 'inline'
  );
  const refElements: IMessageElement[] = [];

  if (elementRegexp) {
    preparedContent = preparedContent.replaceAll(elementRegexp, (match) => {
      const element = elements.find((e) => {
        const nameMatch = e.name === match;
        const scopeMatch =
          isGlobalMatch(e?.forIds) || isForIdMatch(id, e?.forIds);
        return nameMatch && scopeMatch;
      });
      const foundElement = !!element;
      const inlined = element?.display === 'inline';
      if (!foundElement) {
        // Element reference does not exist, return plain text
        return match;
      } else if (inlined) {
        // If element is inlined, add it to the list and return plain text
        if (inlinedElements.indexOf(element) === -1) {
          inlinedElements.push(element);
        }
        return match;
      } else {
        // Element is a reference, add it to the list and return link
        refElements.push(element);
        // spaces break markdown links. The address in the link is not used anyway
        return `[${match}](${match.replaceAll(' ', '_')})`;
      }
    });
  }

  if (language) {
    preparedContent = `\`\`\`${language}\n${preparedContent}\n\`\`\``;
  }
  return {
    preparedContent,
    inlinedElements,
    refElements
  };
}
// console.log('===========aaaaa===========')
// let index = 2;
// let currMessageId = ""
const MessagesData:any[] = []

export default memo(function MessageContent({
  id,
  content,
  elements,
  language,
  authorIsUser,
  isRunning,
  isLast,
  setRandom,
  random,
  type
  // isRendering
}: Props) {
  const { preparedContent, inlinedElements, refElements } = prepareContent({
    id,
    content,
    language,
    elements
  });

  // console.log('id',id)
  const [open, setOpen] = useState(false);
  const [previewUrl, setPreviewUrl] = useState('');
  const [isRendering] = useRecoilState(isRenderingState);
  const client = useRecoilValue(clientState);
  const setVoicing = useSetRecoilState(voicingState);

  const imgPreview = (props: any) => {
    setPreviewUrl(props.src);
    setOpen(true);
  };

  const [text, setText] = useState(preparedContent.slice(0,1));
  const timerIdRef = useRef(null);
  // let currMessageId="";// 当前的消息id;
  // let index = 0;//截取索引
  // console.log('这里执行！！！！')

  useEffect(() => {
    // if(authorIsUser || type === 'welcome') {
    //   setText(preparedContent)
    //   return
    // }
      // 如果不是同一个消息，就从0开始截取
      // console.log('currMessageId=',currMessageId)
      // console.log('id=',id)

    // @ts-ignore
    // console.log(currMessageId,'currMessageId');
    // console.log(id, 'id');
    const index_ = MessagesData.findIndex(res => { 
      return res.currMessageId==id
    })
    if (index_ < 0) {
      MessagesData.push({
        currMessageId: id,
        index: 2
      })
    } 
    if (MessagesData.length > 20) {
      MessagesData.shift()
     }
    // if (currMessageId != id) {
    //   // 初始值从0改为2，使渲染时直接接着第二个字继续渲染
    //     index=2;
    // }
    // @ts-ignore
    // currMessageId = id;
   
    if (!preparedContent) return
    // @ts-ignore
    clearInterval(timerIdRef.current)
    let currentText = '';
    const index_2 = MessagesData.findIndex(res => { 
      return res.currMessageId==id
    })
    // @ts-ignore
    if (authorIsUser) {
      timerIdRef.current = setInterval(() => {
        // console.log('index'+index+'=>')
    if (index_2 !== (MessagesData.length - 1)) { 
      clearInterval(timerIdRef.current);
      client.setAISay('','task_stop')
    }
        currentText = preparedContent.slice(0, MessagesData[index_2].index);
        setText(currentText);
        setRandom(uuidv4())
        MessagesData[index_2].index = MessagesData[index_2].index+1
        // index++;
        if (MessagesData[index_2].index > preparedContent.length) {
          // @ts-ignore
          clearInterval(timerIdRef.current);
          // 只要文字结束输出，就结束一下数字人讲话
          client.setAISay('', 'stream_end')

          // 触发数字人讲话结束，等待中
          if (!authorIsUser) {
            setVoicing('event_vad_end')
          }
        }
      }, 100);
    } else { 
      timerIdRef.current = setInterval(() => {
    if (index_2 !== (MessagesData.length - 1)) { 
      clearInterval(timerIdRef.current);
      client.setAISay('','task_stop')
    }
      // console.log('index'+index+'=>')
      currentText = preparedContent.slice(0, MessagesData[index_2].index);
      setText(currentText);
        setRandom(uuidv4())
        MessagesData[index_2].index = MessagesData[index_2].index+1
      // index++;
      if (MessagesData[index_2].index > preparedContent.length) {
        // @ts-ignore
        clearInterval(timerIdRef.current);
        // 只要文字结束输出，就结束一下数字人讲话
        client.setAISay('','stream_end')

        // 触发数字人讲话结束，等待中
        if(!authorIsUser){
          setVoicing('event_vad_end')
        }
      }
    }, 160);
    }
    
    // @ts-ignore
    return () => clearInterval(timerIdRef.current);
  }, [preparedContent]);


  // const [text, setText] = useState('');
  // const [timer, setTimer] = useState<number | undefined | NodeJS.Timer | null>(null);
  // const [typingIndex, setTypingIndex] = useState<number>(1);

  // useEffect(() => {
  //   if(authorIsUser || type === 'welcome') {
  //     setText(preparedContent)
  //     return
  //   }
  //   if (!preparedContent || type === 'welcome') return

  //   clearTimeout(Number(timer))

  //   //回答
  //   if (!authorIsUser) {
  //     setTimer(setTimeout(() => {
  //       const typingIdx = typingIndex
  //       const text = preparedContent.slice(0, typingIdx)
        
  //       setText(text)
  //       setRandom(uuidv4())
  //       setTypingIndex(typingIdx + 1)
  //       // if (typingIdx >= preparedContent.length) {
  //       //   console.log(typingIdx)
  //       //   clearTimeout(Number(timer))
  //       // }
  //     }, 150))
  //   }
  //   // return () => clearInterval(Number(timer));
  // },[text])


  // 这里停止内容生成 
  useEffect(() => {
    if(!isRendering && !authorIsUser) {
      // @ts-ignore
      clearInterval(timerIdRef.current);
    }   
  }, [ isRendering ])
  // useEffect(() => { 
  //   const index_ = MessagesData.findIndex(res => { 
  //     return res.currMessageId==id
  //   })
  //   console.log(index_,MessagesData.length-1,id);
    
  //   if (index_ !== (MessagesData.length - 1)) { 
      
  //     clearInterval(timerIdRef.current);
  //     client.setAISay('','task_stop')
  //   }
  // },[MessagesData])
  // useEffect(()=>{
  //   return () => {
  //     // 页面退出
  //     console.log('页面退出===')
  //     // @ts-ignore
  //     clearInterval(timerIdRef.current)
  //   };
  // })

  if (!preparedContent) return null;
  return (
   
    <Stack width="100%" sx={{display: 'block'}}>
      <Stack direction="row" sx={
        { 
          backgroundColor: authorIsUser ? 'rgba(7,61,144,0.6)' : 'rgba(130,139,190,0.3)', 
          padding: '10px',
          borderTopLeftRadius: authorIsUser ? '30px' : '10px',
          borderTopRightRadius: authorIsUser ? '10px' : '30px',
          borderBottomRightRadius: authorIsUser ? '0' : '30px',
          borderBottomLeftRadius: authorIsUser ? '30px' : '0',
        }
      }>
        
        <Typography
          sx={{
            width: '100%',
            minHeight: '20px',
            fontSize: '1.1rem',
            lineHeight: '2rem',
            fontFamily: 'Inter',
            fontWeight: 300
          }}
          component="div"
        >
          <ReactMarkdown
            remarkPlugins={[remarkGfm]}
            className="markdown-body"
            components={{
              a({ children, ...props }) {
                const name = children[0] as string;
                const element = refElements.find((e) => e.name === name);

                if (element) {
                  return <ElementRef element={element} />;
                } else {
                  return (
                    <Link {...props} target="_blank">
                      {children}
                    </Link>
                  );
                }
              },
              code({ ...props }) {
                return <Code {...props} />;
              },
              tr({ children }) {
                return (
                  <Box
                    component="tr"
                    sx={{
                      color: 'text.primary',
                      backgroundColor: (theme) => {
                        if (theme.palette.mode === 'light') {
                          return '#fff';
                        } else {
                          return theme.palette.background.default;
                        }
                      }
                    }}
                  >
                    {children}
                  </Box>
                );
              },
              th({ children }) {
                return (
                  <Box
                    component="th"
                    sx={{
                      border: (theme) => {
                        if (theme.palette.mode === 'light') {
                          return '1px solid #d0d7de;';
                        } else {
                          return `1px solid ${theme.palette.divider}`;
                        }
                      }
                    }}
                  >
                    {children}
                  </Box>
                );
              },
              td({ children }) {
                return (
                  <Box
                    component="td"
                    sx={{
                      border: (theme) => {
                        if (theme.palette.mode === 'light') {
                          return '1px solid #d0d7de;';
                        } else {
                          return `1px solid ${theme.palette.divider}`;
                        }
                      }
                    }}
                  >
                    {children}
                  </Box>
                );
              },
              img({ ...props }) {
                return (
                  <Box
                    component="img"
                    onClick={() => imgPreview(props)}
                    style={{ cursor: 'pointer' }}
                    {...props}
                  ></Box>
                );
              },
            }}
          >
            { text }
          </ReactMarkdown>
        </Typography>
        {/* { (!authorIsUser && isLast) && (<div style={{ marginLeft: '5px', marginTop: '2px' }} onClick={handleStopRendering}><img width={20} src={zantingIcon}/></div>) } */}
        </Stack>
      {/* <InlinedElements elements={inlinedElements} /> */}
      <Viewer
        visible={open}
        noNavbar={true}
        showTotal={false}
        noImgDetails={true}
        customToolbar={(toolbars) => {
          return toolbars.concat([
            {
              key: 'download-img',
              render: (
                <div>
                  <i className="react-viewer-icon react-viewer-icon-download"></i>
                </div>
              ),
              onClick: (activeImage) => {
                const link = document.createElement('a');
                link.href = activeImage.src;
                link.target = '_blank';
                link.download = `images.png`;
                link.style.display = 'none';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
              }
            }
          ]);
        }}
        onClose={() => {
          setOpen(false);
        }}
        images={[{ src: previewUrl, downloadUrl: previewUrl }]}
      />
    </Stack>
  );
});
